package com.yy.micro.magic.core.provider;

import com.yy.micro.magic.core.model.PlanSchedule;
import com.yy.micro.magic.core.provider.impl.CodeMapResourceProvider;
import com.yy.micro.magic.core.provider.impl.TriggerResourceProvider;
import com.yy.micro.magic.core.provider.impl.PlanScheduleResourceProvider;
import com.yy.micro.magic.ext.domain.code.CodeMapItem;
import com.yy.micro.magic.ext.domain.filter.DynamicTrigger;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.lang.NonNull;
import org.springframework.stereotype.Component;

import java.util.List;
import java.util.Optional;

import javax.validation.constraints.NotNull;

 /**
   * @author YY
   * @version 1.0.0
   * @update 2021/9/20 6:15 下午
   * @description: 资源提供工厂，用于为magic cube变换时提供静态资源支持。
  * 默认的静态资源由resources下的配置文件提供，{@link ResourceProviderFactory}提供了更灵活的扩展方式，
  * 如数据库、类初始化等实现的可能。主要的静态资源有3种，变换规则paln，动态规则触发器及码表。
 */
@Component
public class ResourceProviderFactory {

    @Autowired(required = false)
    private List<PlanScheduleResourceProvider> planScheduleResourceProviders;
    @Autowired(required = false)
    private List<TriggerResourceProvider> triggerResourceProviders;

    @Autowired(required = false)
    private List<CodeMapResourceProvider> codeMapResourceProviders;

     /**
      * 根据planCode查找{@link PlanSchedule}，如果没有找到则返回null。
      * @param planCode
      * @return
      */
    public PlanSchedule findPlanSchedule(@NonNull String planCode) {
        if (null != planScheduleResourceProviders) {
            Optional<PlanScheduleResourceProvider> provider = planScheduleResourceProviders.stream().filter(p -> null != p.find(planCode)).findFirst();
            if (provider.isPresent()) {
                return provider.get().find(planCode);
            }
        }
        return null;
    }

     /**
      * 根据planCode和当前数据的key（全路径）查找匹配的{@link DynamicTrigger}，如果没有找到则返回 null。
      * @param planCode  planCode
      * @param trigger 源数据某一节点的全路径
      * @return
      */
    public DynamicTrigger findDynamicTrigger(@NonNull String planCode, @NotNull String trigger) {
        if (null != triggerResourceProviders) {
            Optional<TriggerResourceProvider> provider = triggerResourceProviders.stream().filter(p -> null != p.find(planCode, trigger)).findFirst();
            return provider.isPresent() ? provider.get().find(planCode, trigger) : null;
        }
        return null;
    }

     /**
      * 查找码表项，未找到则返回null。
      * @param planCode
      * @param name  码表名
      * @param value  码表中的源value。
      * @return
      */
    public CodeMapItem findCodeItem(String planCode, String name, Object value) {
        if (null != codeMapResourceProviders) {
            Optional<CodeMapResourceProvider> provider = codeMapResourceProviders.stream().filter(p -> null != p.findCodeMapItem(planCode, name, value)).findFirst();
            return provider.isPresent() ? provider.get().findCodeMapItem(planCode, name, value) : null;
        }
        return null;
    }

     /**
      * 查找码表的目标值。码表是源码表与目标码表值间的一一映射，根据源码表中的值找到对应的目标码表的值。
      * @param planCode
      * @param name 码表名
      * @param value  源表值。
      * @return
      */
    public Object findCodeTargetValue(String planCode, String name, Object value) {
        CodeMapItem item = findCodeItem(planCode,name,value);
        if (null != item){
            return item.getTargetValue();
        }
        return null;
    }
}

